#include "stdafx.h"
#include "xKernel/IxNode.h"
#include "xKernel/IxLayout.h"
#include "xKernel/IxLayoutManager.h"
#include "LayoutSchedule.h"

CxLayoutSchedule::CxLayoutSchedule()
    : m_bInLayoutCircle(false)
{}

CxLayoutSchedule::~CxLayoutSchedule()
{}


HRESULT CxLayoutSchedule::AddView(IxView* pView)
{
    if (m_bInLayoutCircle)
    {
        ATLASSERT(!L"It's dangerous to add view to LayoutSchedule in layout circle!!!");
        return E_FAIL;
    }

    CComQIPtr<IxNode> spNode = pView;
    if (!pView || !spNode)
    {
        return E_INVALIDARG;
    }

    if (m_setViews.count(reinterpret_cast<ULONGLONG>(pView)) > 0)
    {
        return S_FALSE;
    }

    INT nDepth = 0;
    spNode->GetDepth(&nDepth);

    m_mapViews.insert(std::make_pair(nDepth, pView));

    return S_OK;
}

HRESULT CxLayoutSchedule::Layout()
{
    if (m_bInLayoutCircle)
    {
        return S_FALSE;
    }

    m_bInLayoutCircle = true;

    CComPtr<IxLayoutManager> spLayoutMgr;
    ::xCommon::GetService(__uuidof(IxLayoutManager), (void**)&spLayoutMgr);
    if (!spLayoutMgr)
    {
        ATLASSERT(!L"obtain layout manager failure!!!");
        return E_FAIL;
    }

    VIEWMAP::iterator it = m_mapViews.begin();
    CComPtr<IxView> spView;
    CComQIPtr<IxLayout> spViewLayout;
    while (it != m_mapViews.end())
    {
        spView = it->second;
        if (spView)
        {
            spViewLayout = it->second;
            if (spViewLayout)
            {
                spViewLayout->Layout(spView);
            }
            else
            {
                INT nType = 0;
                spView->GetLayoutType(&nType);

                CComPtr<IxLayout> spLayout;
                spLayoutMgr->GetLayout(nType, &spLayout);
                if (spLayout)
                {
                    spLayout->Layout(spView);
                }
                else
                {
                    ATLASSERT(!L"didn't find the layout type!!!");
                }
            }
        }
        ++it;
    }

    m_mapViews.clear();

    m_bInLayoutCircle = false;

    return S_OK;
}

//HRESULT CxLayoutSchedule::_add_view(IxView* pView)
//{
//
//}